跳到主要内容

完整性级别

完整性级别是什么?

“完整性级别”(Integrity Level)这个术语在 Windows 操作系统的安全模型中用来表示进程、文件、其他对象的信任级别。这个概念是在 Windows Vista 及其后续版本中引入的,目的是为了防止低信任级别的应用程序对高信任级别的系统组件造成影响。这种机制可以帮助系统防御恶意软件和其他不安全的操作,因为它限制了进程之间可以互相影响的方式。

完整性级别是 Windows 安全模型的一部分,目的是防止恶意软件通过较低权限的进程来影响或控制具有较高权限的进程。这些级别从低到高主要包括:

  • 低(Low)
  • 中(Medium)
  • 高(High)
  • 系统(System)

如果你试图从一个完整性级别较低的进程中访问或修改另一个具有较高完整性级别的进程的资源,你可能会看到这样的错误消息,表明操作因权限不足而被拒绝。

例如,如果一个普通用户级别的应用程序(通常为中级完整性)试图修改一个管理员级别的应用程序(通常为高级完整性)的设置或文件,操作系统会拒绝这种访问,因为这可能导致安全风险。

解决这种问题通常需要提升你的进程的权限,比如通过右键点击程序图标并选择“以管理员身份运行”,从而使程序运行在较高的完整性级别上。

使用 C++ 检查和修改完整性级别

在C++中,你可以通过Windows API来处理和修改进程的完整性级别。这通常涉及到获取和设置安全标识符(SID),并使用这些SID作为访问令牌的一部分来定义进程的完整性级别。下面是一个简单的例子,展示如何在C++中检查当前进程的完整性级别,并尝试以不同完整性级别创建一个新进程。

首先,你需要包含必要的头文件并链接必要的库:

#include <Windows.h>
#include <iostream>
#include <sddl.h> // 用于安全描述符定义语言(SDDL)相关操作

#pragma comment(lib, "advapi32.lib") // 链接高级Windows 32基本API库

接下来,定义一个函数来获取当前进程的完整性级别:

void CheckCurrentProcessIntegrityLevel() {
HANDLE hToken;
DWORD dwLengthNeeded;
DWORD dwError = ERROR_SUCCESS;
PTOKEN_MANDATORY_LABEL pTIL = NULL;
LPWSTR pStringSid;
DWORD dwIntegrityLevel;

if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
// 首先获取所需的大小
if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwLengthNeeded) &&
(dwError = GetLastError()) == ERROR_INSUFFICIENT_BUFFER) {
pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(LPTR, dwLengthNeeded);
if (pTIL != NULL) {
if (GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwLengthNeeded, &dwLengthNeeded)) {
dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1));

if (ConvertSidToStringSid(pTIL->Label.Sid, &pStringSid)) {
std::wcout << L"当前进程的完整性级别 SID 为: " << pStringSid << std::endl;

// 根据SID值判断完整性级别
if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID) {
std::wcout << L"低级完整性级别" << std::endl;
} else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID &&
dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID) {
std::wcout << L"中级完整性级别" << std::endl;
} else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID &&
dwIntegrityLevel < SECURITY_MANDATORY_SYSTEM_RID) {
std::wcout << L"高级完整性级别" << std::endl;
} else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID) {
std::wcout << L"系统级完整性级别" << std::endl;
}
LocalFree(pStringSid);
}
}
LocalFree(pTIL);
}
}
CloseHandle(hToken);
}
}

这个函数首先打开当前进程的访问令牌,然后获取与令牌关联的完整性级别信息。这里使用的是 GetTokenInformation 函数,通过该函数可以检索当前进程的完整性级别并打印出来。

注意,为了实际在你的应用程序中实现跨完整性级别的操作,你可能需要使用更高级的权限提升技术,或在不同完整性级别下启动新的进程。这通常涉及到复杂

的权限管理和安全考虑,可能需要管理员权限或调用特定的API函数,如CreateProcessAsUser。在实际操作中,这通常是为了提高安全性而避免的,除非绝对必要。